/**
    算法描述：
    核心问题：
    解决所需数据结构+算法：
**/
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

struct edge
{
    /* data */
    int x, y, c, pre, other;
}a[20500];
int alen = 0, last[500] = {0};

void ins(int x, int y, int c) {
    a[++alen] = edge{x, y, c, last[x], alen+1};
    last[x] = alen;
    a[++alen] = edge{y, x, 0, last[y], alen-1};
    last[y] = alen;
}

int h[500], st, ed;

bool bfs() {
    memset(h, 0, sizeof(h));
    queue<int> q;
    q.push(st);
    h[st] = 1;
    while(!q.empty()) {
        int x = q.front();
        for(int k=last[x]; k; k=a[k].pre) {
            int y = a[k].y;
            if(!h[y] && a[k].c>0) {
                h[y] = h[x] + 1;
                q.push(y);
            }
        }
        q.pop();
    }
    return h[ed] > 0;
}

int dfs(int x, int flow) {
    int sx = 0;
    if (x == ed)
        return flow;
    for(int k=last[x]; k; k=a[k].pre) {
        int y = a[k].y;
        if(sx<flow && h[y]==h[x]+1 && a[k].c>0) {
            int sy = dfs(y, min(flow-sx, a[k].c));
            a[k].c -= sy;
            a[a[k].other].c += sy;
            sx += sy;
        }
    }
    if (sx == 0)
        h[x] = 0;
    return sx;
}

int main() {
    int n, f, d, mx = 0;
    scanf("%d%d%d", &n, &f, &d);
    // 顶点编号分别是：f, f+n, f+2*n, f+2*n+d
    st = f + 2*n + d + 1;
    ed = st + 1;
    // 连肉
    for(int i=1; i<=f; i++)
        ins(st, i, 1);
    // 连饮料
    for(int i=1; i<=d; i++)
        ins(f+2*n+i, ed, 1);
    // 连牛A和牛B
    for(int i=1; i<=n; i++)
        ins(f+i, f+n+i, 1);
    // 连牛和肉、饮料
    for (int i=1; i<=n; i++) {
        int fi, di, id;
        scanf("%d%d", &fi, &di);
        while(fi--) {
            scanf("%d", &id);
            ins(id, d+i, 1);
        }
        while(di--) {
            scanf("%d", &id);
            ins(f+n+i, f+2*n+id, 1);
        }
    }
    while(bfs())
        mx += dfs(st, 0x3fffffff);
    printf("%d\n", mx);
    return 0;
}